https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html
tested on ubuntu 20.04
install cgroup-tools (may be called
libcgroup on other distributions)
apt-get install cgroup-tools
fetch cgred.conf from sample configuration
cp /usr/share/doc/cgroup-tools/examples/cgred.conf /etc/
create cgconfig.conf
vim /etc/cgconfig.conf
with the following content:
group chromium {
# limit cpu to 2 cores : 2*100 percent *1000
cpu {
cpu.cfs_quota_us=200000;
}
# limit memory to 1 GB
memory {
memory.limit_in_bytes = 1024m;
}
}
create cgrules.conf
vim /etc/cgrules.conf
with the following content:
#<user> <controllers> <destination>
#<user>:<process name> <controllers> <destination>
dealingtrap:/snap/bin/chromium cpu,memory chromium
test the configuration by parsing the setting and launching the daemon
/usr/sbin/cgconfigparser -l /etc/cgconfig.conf
/usr/sbin/cgrulesengd -vvv
confirm that no task are currently managed by the new cgroup
chromium
cat /sys/fs/cgroup/cpu/chromium/tasks
restart chromium in userspace and check that the new process is managed by the new cgroup
cat /sys/fs/cgroup/cpu/chromium/tasks
create cgconfigparser.service
vim /etc/systemd/system/cgconfigparser.service
with the following content:
[Unit]
Description=cgroup config parser
After=network.target
[Service]
User=root
Group=root
ExecStart=/usr/sbin/cgconfigparser -l /etc/cgconfig.conf
Type=oneshot
[Install]
WantedBy=multi-user.target
create cgrulesgend.service
vim /etc/systemd/system/cgrulesgend.service
with the following content:
[Unit]
Description=cgroup rules generator
After=network.target cgconfigparser.service
[Service]
User=root
Group=root
Type=forking
EnvironmentFile=-/etc/cgred.conf
ExecStart=/usr/sbin/cgrulesengd
Restart=on-failure
[Install]
WantedBy=multi-user.target
And activate the new systemd services
systemctl daemon-reload
systemctl enable cgconfigparser
systemctl enable cgrulesgend
systemctl start cgconfigparser
systemctl start cgrulesgend
On ubuntu the kernel requires some flag being enabled to allow swap control per process.
Edit kernel options in grub configuration:
sudoedit /etc/default/grub
add the fllowing options to GRUB_CMDLINE_LINUX:
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
save the config and update grub:
sudo update-grub
After a reboot memory.memsw.* settings are now available
in cgroups
Sample /etc/cgconfig.conf:
group chromium {
# limit cpu to 2 cores : 2*100 percent *1000
cpu {
cpu.cfs_quota_us=200000;
}
# limit memory to 2 GB
memory {
memory.limit_in_bytes = 2048m;
memory.memsw.limit_in_bytes = 2048m;
memory.swappiness = 0;
}
}
group firefox {
# limit cpu to 4 cores : 4*100 percent *1000
cpu {
cpu.cfs_quota_us=400000;
}
# limit memory to 3 GB
memory {
memory.limit_in_bytes = 3072m;
memory.memsw.limit_in_bytes = 3072m;
}
}
group evolution {
# limit cpu to 2 cores : 2*100 percent *1000
cpu {
cpu.cfs_quota_us=200000;
}
# limit memory to 1 GB
memory {
memory.limit_in_bytes = 1024m;
memory.memsw.limit_in_bytes = 1024m;
}
}
group rambox {
# limit cpu to 2 cores : 2*100 percent *1000
cpu {
cpu.cfs_quota_us=200000;
}
# limit memory to 2 GB
memory {
memory.limit_in_bytes = 2048m;
memory.memsw.limit_in_bytes = 2048m;
}
}
group teams {
# limit cpu to 2 cores : 2*100 percent *1000
cpu {
cpu.cfs_quota_us=200000;
}
# limit memory to 1.5 GB
memory {
memory.limit_in_bytes = 1536m;
memory.memsw.limit_in_bytes = 1536m;
}
}
Sample /etc/cgrules.conf:
#<user> <controllers> <destination>
#<user>:<process name> <controllers> <destination>
dealingtrap:/snap/bin/chromium cpu,memory chromium
dealingtrap:chrome cpu,memory chromium
dealingtrap:/usr/bin/firefox cpu,memory firefox
dealingtrap:/usr/bin/evolution cpu,memory evolution
dealingtrap:/usr/libexec/evolution-data-server/evolution-alarm-notify cpu,memory evolution
dealingtrap:/usr/libexec/evolution-calendar-factory cpu,memory evolution
dealingtrap:/usr/libexec/evolution-addressbook-factory cpu,memory evolution
dealingtrap:/usr/libexec/evolution-source-registry cpu,memory evolution
dealingtrap:/usr/bin/rambox cpu,memory rambox
dealingtrap:/opt/Rambox/rambox cpu,memory rambox
dealingtrap:/usr/bin/teams cpu,memory teams
Restart cg services to load the new configuration
systemctl restart cgconfigparser
systemctl restart cgrulesgend
Cgroups are applied at process creation, so be sure to restart the userspace process you want to see associated with a cgroup
For launching a process as non-superuser with cpu, memory and I/O limits:
systemd-run --user --scope -p MemoryLimit=1G -p CPUShares=2048 -p BlockIOWeight=500 firefox
A scope is a systemd unit (a process container) that is not a service.
To allow user to create slices managing more than memory and pids (cpu and io, but ebpg and rdma cannot be delegated), edit the user service corresponding to you user uid with the following command:
sudo systemctl edit user@1000.service
and add the following content:
[Service]
Delegate=yes
Then, edit ~/.config/systemd/user/firefox.slice and add
the following content:
[Slice]
MemoryAccounting=true
MemoryMax=256M
CPUAccounting=true
CPUQuota=25%
the slice ca now be used to contain scopes launch by the following command:
systemd-run --user --slice firefox --scope firefox
To control a systemd service here are some useful unit settings:
sudo systemctl edit foo.service --full
edit or add all or some of the following under the
[Service] tag:
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
CPUQuota=200%
MemoryMax=1G
MemorySwapMax=0
IOWeight=20
CPUWeight=20
and restart the service:
sudo systemctl restart foo.service
as an exemple: /etc/systemd/system/eea.service:
[Unit]
Description=ESET Endpoint Antivirus
After=network.target
[Service]
Type=simple
ExecStartPre=/opt/eset/eea/lib/install_scripts/check_start.sh
ExecStart=/opt/eset/eea/sbin/startd
ExecStartPost=/bin/sleep 2
ExecStartPost=-/opt/eset/eea/lib/install_scripts/launch_gui_all_users.sh
ExecStopPost=-/usr/bin/killall /opt/eset/eea/lib/egui --quiet
KillMode=process
Restart=always
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
CPUQuota=200%
MemoryMax=1G
MemorySwapMax=0
IOWeight=20
CPUWeight=20
[Install]
WantedBy=multi-user.target
Last modified: Sat Sep 13 01:55:42 2025